现在很多应用都提供了双击 BACK 键退出的功能,用不算高的操作成本,来增加用户的留存时间,也降低了误触的风险。

今天介绍一下如何实现这个功能。

Android 中没有直接提供监听双击 BACK 键的方法,所以我们要自己实现。思路大概是监听 BACK 键是否有点击事件,有的话判断是第几次点击,并设置一个时间来对点击的状态进行重置,避免两次点击相差时间过长也可以响应的情况。

好的,接下来就是实现了:

利用线程延时

public class MainActivity extends Activity {
    ...
    private static boolean mBackKeyPressed = false;     // 记录是否有首次按键
    
    @Override
    public void onBackPressed() {
        if (!mBackKeyPressed) {
            Toast.makeText(this, "Click again to exit", Toast.LENGTH_SHORT).show();
            mBackKeyPressed = true;
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    mBackKeyPressed = false;
                }
            }, 2000);
        } else {
            super.onBackPressed();
        }
    }
}

这里定义了一个 boolean 类型的变量来记录是否已经点击过 BACK 键,如果没有,则给出提示,让用户再点一次退出,如果已经点击过一次,那么这次响应就直接退出应用。

监听 BACK 键的方法在『Android 为 WebView 重写 Back 键』一文有相关介绍,这里选取了 onBackPressed() 来进行监听,通过 Timer 来设置响应间隔,即 2 秒内如果不退出应用,则对第一次点击擦除。

通过计算时间差

public class MainActivity extends Activity {
    ...
    private long mPressedTime = 0;

    @Override
    public void onBackPressed() {
        long mNowTime = System.currentTimeMillis();
        if ((mNowTime - mPressedTime) > 2000) {
            Toast.makeText(this, "Click again to exit", Toast.LENGTH_SHORT).show();
            mPressedTime = mNowTime;
        } else {
            super.onBackPressed();
        }
    }
}

这里定义一个 long 类型的变量用来记录用户点击 BACK 键时的时间,默认为 0,表示没有点击,并在 onBackPressed() 内获取到点击 BACK 键时的时间,然后作判断,假如差大于 2 秒,则给出提示,让用户再点一次退出,如果小于 2 秒,则直接退出应用。

该方法不像上方线程延迟将状态重置为初始值,这里每次超时点击都会将 mPressedTime 置为当时点击的时间,也就是说该值会不断增长,直至退出应用。


实现效果如下

双击 Back 键退出

这里顺便再给个反例,是广发银行旗下的信用卡应用『发现精彩』的双击退出实现:

发现精彩退出逻辑

『发现精彩』使用的是弹窗而非 Toast,当用户连续双击 BACK 键后,才会给出弹窗,也就是说正常情况下用户需要点击三次才能成功退出,无形中就增加了用户的点击成本。

另外,当用户连续点击奇数次时,弹窗会消失,但应用不会退出,如此反复。用户平时如果进入多个页面后,点击 BACK 键会将多个页面出栈,直至最后一个页面才会退出,那么当用户所处的页面为非主页而用户此时想退出时,就会一直连续点击 BACK 键,由于点击过于迅速,用户也不会在意自己点了多少次,所以很大几率会导致弹窗消失,使用户的点击成本越来越高,这种交互一定是产品经理脑抽才会想出来的。